package com.cgs.mongo.delegate;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.mongodb.Block;
import com.mongodb.Function;
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoIterable;
import com.mongodb.client.model.Collation;
import com.mongodb.lang.Nullable;
import org.bson.Document;
import org.bson.conversions.Bson;

import java.util.Collection;
import java.util.Map;
import java.util.Spliterator;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

import static com.cgs.mongo.utils.WrapperUtils.asBsonDocument;

public class AggregateIterableWrapper<TDocument> implements AggregateIterable<TDocument> {

    private AggregateIterable<TDocument> delegate;

    public AggregateIterableWrapper(AggregateIterable<TDocument> delegate) {
        this.delegate = delegate;
    }

    @Override
    public void toCollection() {
        delegate.toCollection();
    }

    @Override
    public AggregateIterable<TDocument> allowDiskUse(Boolean allowDiskUse) {
        return delegate.allowDiskUse(allowDiskUse);
    }

    @Override
    public AggregateIterable<TDocument> batchSize(int batchSize) {
        return delegate.batchSize(batchSize);
    }

    @Override
    public AggregateIterable<TDocument> maxTime(long maxTime, TimeUnit timeUnit) {
        return delegate.maxTime(maxTime, timeUnit);
    }

    public AggregateIterable<TDocument> maxTimeSeconds(long maxTime) {
        return delegate.maxTime(maxTime, TimeUnit.SECONDS);
    }

    @Override
    @Deprecated
    public AggregateIterable<TDocument> useCursor(Boolean useCursor) {
        return delegate.useCursor(useCursor);
    }

    @Override
    public AggregateIterable<TDocument> maxAwaitTime(long maxAwaitTime, TimeUnit timeUnit) {
        return delegate.maxAwaitTime(maxAwaitTime, timeUnit);
    }

    @Override
    public AggregateIterable<TDocument> bypassDocumentValidation(Boolean bypassDocumentValidation) {
        return delegate.bypassDocumentValidation(bypassDocumentValidation);
    }

    @Override
    public AggregateIterable<TDocument> collation(Collation collation) {
        return delegate.collation(collation);
    }

    @Override
    public AggregateIterable<TDocument> comment(String comment) {
        return delegate.comment(comment);
    }

    @Override
    public AggregateIterable<TDocument> hint(Bson hint) {
        return delegate.hint(hint);
    }

    public AggregateIterable<TDocument> hint(Map<String, Object> hint) throws JsonProcessingException {
        return delegate.hint(asBsonDocument(hint));
    }

    @Override
    public MongoCursor<TDocument> iterator() {
        return delegate.iterator();
    }

    @Override
    @Nullable
    public TDocument first() {
        return delegate.first();
    }

    @Override
    public <U> MongoIterable<U> map(Function<TDocument, U> mapper) {
        return delegate.map(mapper);
    }

    @Override
    @Deprecated
    public void forEach(Block<? super TDocument> block) {
        delegate.forEach(block);
    }

    @Override
    public <A extends Collection<? super TDocument>> A into(A target) {
        return delegate.into(target);
    }

    @Override
    public void forEach(Consumer<? super TDocument> action) {
        delegate.forEach(action);
    }

    @Override
    public Spliterator<TDocument> spliterator() {
        return delegate.spliterator();
    }
}
